﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using IntelligentDecisioning.SharePoint.Definition;
using IntelligentDecisioning.SharePoint.Logging;

namespace IntelligentDecisioning.SharePoint.Helpers
{
    public class IDSecurityHelper: IDSharePointHelper
    {
        #region Constructor

        public IDSecurityHelper(SPSite siteCollection, SPWeb targetWeb)
            : base(siteCollection, targetWeb, new NoLog())
        {

        }

        public IDSecurityHelper(SPSite siteCollection, SPWeb targetWeb, ILog log)
            : base(siteCollection, targetWeb, log)
        {

        }

        #endregion

        #region Methods

        #region Create Root Site Group
        /// <summary>
        /// Create a new secuiruty group in the root site unless the group already exisits
        /// </summary>
        /// <param name="name"></param>
        /// <param name="description"></param>
        public void CreateRootSiteGroup(String name, String description)
        {
            if (HasGroup(RootWeb, name) == false)
            {
                SPUser currentUser = RootWeb.CurrentUser;
                RootWeb.SiteGroups.Add(name, currentUser, currentUser, description);
                Log.WriteToLog("Added site group " + name);
            }
            else
            {
                Log.WriteToLog("site group " + name + " already exists");
            }
        }

        #endregion


        #region Create Current Site Group

        /// <summary>
        /// Create a new security group in the current site unless the group already exists
        /// </summary>
        /// <param name="name"></param>
        /// <param name="description"></param>
        public void CreateCurrentSiteGroup(string name, string description)
        {
            if (HasGroup(RootWeb, name) == false)
            {
                SPUser currentUser = TargetWeb.CurrentUser;
                TargetWeb.SiteGroups.Add(name, currentUser, currentUser, description);
                Log.WriteToLog("Added web group " + name);
            }
            else
            {
                Log.WriteToLog("Web group " + name + " already exists");
            }
        }

        #endregion


        #region Methods to find site groups by name

        /// <summary>
        /// Retuns the root site group specified or null if the group does not exist
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public SPGroup GetRootSiteGroup(string name)
        {
            return GetGroup(RootWeb, name);
        }

        /// <summary>
        /// Returns the target group specified or null if the group does not exist
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public SPGroup GetTargetSiteGroup(string name)
        {
            return GetGroup(TargetWeb, name);
        }

        /// <summary>
        /// Returns the group specified or null if the group does not exist
        /// </summary>
        /// <param name="web"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public SPGroup GetGroup(SPWeb web, String name)
        {
            SPGroup group = null;

            foreach (SPGroup siteGroup in web.SiteGroups)
            {
                if (siteGroup.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
                {
                    group = siteGroup;
                    break;
                }
            }

            return group;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="web"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool HasGroup(SPWeb web, string name)
        {
            bool groupExists = false;

            foreach (SPGroup siteGroup in web.SiteGroups)
            {
                if (siteGroup.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
                {
                    groupExists = true;
                }
            }

            return groupExists;
        }

        #endregion

        #endregion

        #region Provision Security groups

        public void ProvisionCustomGroups(List<SecurityGroup> customGroups)
        {
            Log.WriteToLog("There are " + customGroups.Count + " Security groups to provision");

            foreach (SecurityGroup securityGroup in customGroups)
            {
                if (securityGroup.Scope == Scope.SiteCollection)
                {
                    CreateRootSiteGroup(securityGroup.Name, securityGroup.Description);
                }
                else // current web
                {
                    CreateCurrentSiteGroup(securityGroup.Name, securityGroup.Description);
                }
            }
        }

        #endregion

        #region Notify Site Administrators

        // TODO: This method is in the wrong the place
        internal void NotifySiteAdministrators(string subject, string message)
        {
            foreach (SPUser user in TargetWeb.AllUsers)
            {
                if (user.IsSiteAdmin)
                {
                    SendEmail(user, subject, message);
                }
            }
        }

        #endregion
    }
}
